﻿module Sustainalytics.Navigation {

    import Common = Sustainalytics.Common;

    export class SiteMapNode {

        public code: string;
        public title: string;
        public path: string;
        public nodes: SiteMapNode[];
        public order: number;
        public userData: any;
        public isSelected: boolean;

        private nodesDic: Common.Dictionary<SiteMapNode>;
        private lastOrder: number = 0;

        public formattedPath: string;
        public level: number;
        public parent: SiteMapNode;

        // route details associated to current node
        public route: SiteMapNodeRoute;

        // route resolver for current node and its descendants
        private nodeRouteResolverService: ISiteMapNodeRouteResolverService;


        constructor(node: ISiteMapNode, nodeRouteResolverService: ISiteMapNodeRouteResolverService, level: number = 0) {

            var ctx = this;

            ctx.level = level;

            ctx.code = node.code;
            if (!ctx.code)
                throw 'Node code is not valid.';

            ctx.title = node.title;
            ctx.path = node.path && node.path !== '' ? node.path : node.code;
            ctx.userData = node.userData;

            ctx.nodesDic = new Common.Dictionary<SiteMapNode>();

            if (node.nodes && node.nodes.length > 0) {
                var newNodes = $.map(node.nodes, function (node, index) {
                    return new SiteMapNode(node, nodeRouteResolverService, ctx.level + 1);
                });

                // add nodes
                ctx.addNodes(newNodes);
            }
            else {
                ctx.nodes = [];
            }

            //ctx.nodesDic = new Common.Dictionary<SiteMapNode>();

            ctx.nodeRouteResolverService = nodeRouteResolverService;
        }

        public addNodes(newNodes: SiteMapNode[], order?: number) {
            var ctx = this;

            // determine current order
            var currentOrder = order ? order : ctx.lastOrder + 1;

            // add each node to dictionary
            newNodes.forEach(function (newNode, index) {
                //newNode.level = ctx.level + 1;
                newNode.parent = ctx;

                ctx.nodesDic.add(currentOrder.toString(), newNode);

                if (currentOrder > ctx.lastOrder) {
                    ctx.lastOrder = currentOrder;
                }

                currentOrder += 1;
            });

            // recreate nodes array
            ctx.nodes = ctx.nodesDic.getValues();
        }

        // evaluate node route
        public evalNodeRoute(): ng.IPromise<any> {
            var ctx = this;

            if (ctx.nodeRouteResolverService) {
                var routePromise = ctx.nodeRouteResolverService.resolveNodeRoute(ctx);

                routePromise.then(function (route) {
                    ctx.route = route;
                });

                return routePromise;
            }
            else {
                return null;
            }
        }
    }
}